package gbench.appdemo.mall.junit;

import static gbench.common.tree.LittleTree.MFT;
import static gbench.common.tree.LittleTree.IRecord.*;

import java.io.File;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.jupiter.api.Test;

import gbench.common.fs.FileSystem;
import gbench.common.tree.LittleTree.IRecord;
import gbench.common.tree.LittleTree.SQL;
import gbench.commonApp.data.DataApp;

public class JunitMall {
    
    /**
     * 
     * 
     * @author gbench
     *
     */
    public class MyDataApp extends DataApp {

        /**
         * 
         * @param name 数据库名称
         */
        public MyDataApp(String dbname) {
            this.dbname = dbname;
            this.reload(this.configureDbName(dbname));
        }

        /**
         * 数据查询
         * 
         * @param sql sql 语句
         * @return IRecord 集合
         */
        public List<IRecord> sqlquery(final String sql, String dbname) {
            reload(this.configureDbName(dbname));
            return this.jdbc.sql2records(sql);
        }

        /**
         * 数据查询
         * 
         * @param sql sql 语句
         * @return IRecord 集合
         */
        public List<IRecord> sqlquery(final String sql) {
            return this.sqlquery(sql, dbname);
        }

        /**
         * 配置数据库
         * 
         * @param dbname
         * @return 设定数据库
         */
        public IRecord configureDbName(final String dbname) {
            return cfg.derive("url", MFT("jdbc:mysql://localhost:3306/{0}?serverTimezone=GMT%2B8", dbname));
        }

        private String dbname; // 数据库名称

    }
    
    @Test
    public List<IRecord> getProducts() {
        final var path = "D:\\sliced\\files\\product";
        final var ll = new LinkedList<IRecord>();
        FileSystem.tranverse(new File(path), f->{
            final var name = FileSystem.namepicker(f.getName());
            final var rec = REC("name",name.replaceFirst("\\..*$", ""),
                "path",f.getAbsolutePath().replace('\\', '/'));
            ll.add(rec);
            System.out.println(rec);
        });
        return ll;
    }
    
    @Test
    public List<IRecord> getUsers() {
        final var path = "D:\\sliced\\files\\user";
        final var ll = new LinkedList<IRecord>();
        FileSystem.tranverse(new File(path), f->{
            final var name = FileSystem.namepicker(f.getName());
            final var rec = REC("name",name.replaceFirst("\\..*$", ""),
                "path",f.getAbsolutePath().replace('\\', '/'));
            ll.add(rec);
            System.out.println(rec);
        });
        return ll;
    }

    @Test
    public void foo() {
        final var dataApp = new MyDataApp("db1");// 打开一个数据库 db1,db1 需要在创建
        final var builder = IRecord.builder("#id,~32name,128path,price,createtime");// 产品信息表
        final var rec = builder.get(1l, "name","",28.5,LocalDateTime.now());// 生成一个数据示意图
        final var database = dataApp.getDataBase(); // 获取数据库对象
        final var tableName = "t_products";// 默认表名
        final var namedsql = new SQL(tableName, rec);
        final var createsqls = namedsql.createTable();
        final var ai = new AtomicInteger(0);
        System.out.println("创建数据表  sql:");
        createsqls.stream().forEach(System.out::println);
        
        System.out.println("\n分录明细:");
        dataApp.withTransaction(sess -> {
            if(database.exists(tableName)) sess.sqlexecute(MFT("drop table {0}",tableName));
            for(int i=2;i<createsqls.size();i++) sess.sqlexecute(createsqls.get(i));// 创建产品sql表
            
            final List<String> sqls = this.getProducts().stream().limit(100)
                .flatMap(line-> Stream.of ( // 生成借贷分录
                    new SQL(tableName,rec.derive(
                        "id",ai.getAndIncrement(),
                        "name",line.get("name"),
                        "path",line.get("path")
                    )).insert()
                )).collect(Collectors.toList());
            for(var s:sqls) {
                System.out.println(s);
                sess.sqlexecute(s);
            }
            //
            final var recs = sess.sql2records(MFT("select * from {0}",tableName));
            recs.forEach(e -> {
                System.out.println(e);
            });
        });
    }
    
    @Test
    public void bar() {
        final var dataApp = new MyDataApp("db1");// 打开一个数据库 db1,db1 需要在创建
        final var builder = IRecord.builder("#id,~32name,8sex,128path,createtime,account"); // 人员信息表
        final var rec = builder.get(1l, "name","man","path",LocalDateTime.now(),"account");// 生成一个数据示意图
        final var tableName = "T_USER";// 默认表名
        final var namedsql = new SQL(tableName, rec);
        final var createsqls = namedsql.createTable(true);// 启用主键自增长
        System.out.println("创建数据表  sql:");
        createsqls.stream().forEach(e->System.out.println("\n"+e));
        
        System.out.println("\n插入数据:");
        dataApp.withTransaction(sess -> {
            sess.sqlexecute(createsqls.get(0));// 删除数据表
            for(int i=2;i<createsqls.size();i++) sess.sqlexecute(createsqls.get(i));// 创建产品sql表
            final var proto = rec.remove("#id");// 去掉主键id
            final List<String> sqls = this.getUsers().stream().limit(100)
            .flatMap(line-> Stream.of ( // 生成借贷分录
                new SQL(tableName,proto.derive(
                    "name",line.get("name"),
                    "account",line.get("name"),
                    "path",line.get("path")
                )).insert()
            )).collect(Collectors.toList());
            
            for(var s:sqls) {
                System.out.println(s);
                sess.sqlexecute(s);
            }
            
            //查询插入的结果
            final var recs = sess.sql2records(MFT("select * from {0}",tableName));
            recs.forEach(e -> {
                System.out.println(e);
            });
        });
    }

}
